var express = require('express');
var path = require('path');
var _ = require('underscore');
var config = require('./config');
var fileUpload = require('express-fileupload');
var fs = require('fs');
var mkdirp = require("mkdirp");
var moment = require('moment');
var uuid = require('node-uuid');
var crypto = require('crypto');
var argv = require('yargs').argv;

var app = express();
var httpPort = Number(argv._[0]) || 3000;
app.set('views', './views');
app.set('view engine', 'jade');
app.use('/static', express.static('static'));
app.use(fileUpload());

app.post('/upload', function (req, res, next) {
  var tag = req.query.tag;
  var memo = req.query.memo;
  var relativePath = req.query.relativePath;
  var project = _.find(config.projects, function (p) { return p.name == req.query.project; });
  if (project == undefined) {
    res.json({ "success": false, "stop": true, "message": 'project:' + req.query.project + ' 不存在' });
    return;
  }
  ProjectInit(project);
  if (project.directory.substr(project.directory.length - 1) == "\\") {
    project.directory = project.directory.substr(0, project.directory.length - 1);
  }

  var user = _.find(project.users, function (p) { return p.account == req.query.account; });
  if (user == undefined) {
    res.json({ "success": false, "stop": true, "message": '帐号密码错误' });
    return;
  }

  var sampleFile;
  if (!req.files) {
    res.json({ "success": false, "stop": false, "message": '没有上传文件' });
    return;
  }
  sampleFile = req.files.file;
  var password = crypto.createHash('md5').update(new Buffer(sampleFile.data)).digest('hex') + user.password + relativePath;
  var password = crypto.createHash('md5').update(password).digest('hex');
  if (password != req.query.password) {
    res.json({ "success": false, "stop": true, "message": '帐号密码错误' });
    return;
  }

  var filePath = project.directory + relativePath;
  var directory = filePath.substr(0, filePath.lastIndexOf("\\"));

  CreateDire(directory, function (err) {
    if (err) {
      console.error(err);
      res.json({ "success": false, "stop": false, "message": '创建目录出错' + directory });
      return;
    }
  });


  var currentPath = path.resolve();
  var fileInfo = FileFormat(relativePath);
  var fileUuid = uuid.v1().substr(0, 8);
  var fileOld = fileInfo.directory + tag + '-' + fileInfo.name + '-old-' + fileUuid;
  var fileNew = fileInfo.directory + tag + '-' + fileInfo.name + '-new-' + fileUuid;
  if (fileInfo.hasExtension) {
    fileOld = fileOld + '.' + fileInfo.extension;
    fileNew = fileNew + '.' + fileInfo.extension;
  }
  var yyyymmdd = moment().format('YYYYMMDD');
  var historyPath = path.resolve('data', project.name, 'history', yyyymmdd);

  var logPath = path.normalize(path.resolve('data', project.name) + '\\' + yyyymmdd + '-'+tag+'.json');
  var log = {
    data: moment().format('YYYY-MM-DD HH:mm:ss'),
    tag: tag,
    account: user.account,
    memo: memo,
    target: relativePath,
    old: path.normalize(historyPath + fileOld).replace(currentPath, ''),
    new: path.normalize(historyPath + fileNew).replace(currentPath, '')
  };
  CreateDire(historyPath + fileInfo.directory);
  if (fs.existsSync(project.directory + relativePath)) {
    fs.createReadStream(project.directory + relativePath).pipe(fs.createWriteStream(currentPath + log.old));
  } else {
    log.old = '';
  }
  console.log(log);

  sampleFile.mv(currentPath + log.new, function (err) {
    if (err) {
      res.json({ "success": false, "stop": false, "message": '错误' + err });
      return;
    } else {
      console.log(filePath + "上传成功");
      //根据配置对文件做进一步的处理
      FileHandler(log.target,currentPath + log.new,project.fileHandlers,currentPath);
      //写入log
      FileAppend(logPath, JSON.stringify(log) + ',');
      //将新文件copy到 project.directory + log.target
      fs.createReadStream(currentPath + log.new).pipe(fs.createWriteStream(project.directory + log.target));
      res.json({ "success": true, "stop": false, "message": '创建目录出错' });
      return;
    }
  });

});

app.listen(httpPort);
console.log('The depolyServer is now ready to accept connections on port %s',httpPort);

//初始化Project目录
function ProjectInit(project) {
  var basePath = path.normalize(path.resolve('data', project.name));
  var historyPath = path.normalize(path.resolve('data', project.name, 'history'));
  CreateDire(basePath);
  CreateDire(historyPath);
}

//创建目录 同步
function CreateDire(path, cb) {
  mkdirp.sync(path, function (err) {
    if (cb) cb(err);
    if (err) {
      console.error('创建目录出错' + err);
      return;
    }
  });
}

//向某个文件追加内容
function FileAppend(file, content) {
  fs.writeFileSync(file, content, { 'flag': 'a' }, function (err) {
    if (err) {
      throw err;
    }
  });
}

function FileFormat(filePath) {
  var directory = ''; 
  var name = '';
  var extension = '';
  var hasExtension = true;
  var fullName = '';

  var index = filePath.lastIndexOf('\\');
  if (index != -1) {
    directory = filePath.substr(0, index + 1);
    filePath = filePath.substr(index + 1);
  }
  var index = filePath.lastIndexOf('.');
  if (index != -1) {
    fullName = filePath;
    name = filePath.substr(0, index);
    extension = filePath.substr(index + 1);
  } else {
    fullName = filePath;
    name = filePath;
    hasExtension = false;
  }
  return {
    directory: directory,
    fullName: fullName,
    name: name,
    extension: extension,
    hasExtension: hasExtension
  };
}

function FileHandler(target, filePath, fileHandlers,currentPath) {
  fileHandlers = fileHandlers || [];
  if (fileHandlers.constructor == Object) fileHandlers = [fileHandlers];
  if (fileHandlers.constructor != Array) return;
  for (var i = 0, item; item = fileHandlers[i]; i++) {
    if(item.filePath.toLocaleLowerCase() == target.toLocaleLowerCase()){
      for(var j=0,rule;rule=item.rules[j];j++){
        switch(rule.name.toLocaleLowerCase()){
          case "a":
            fs.createReadStream(currentPath + rule.p1).pipe(fs.createWriteStream(filePath));
            break;
          case "b":
            var content = fs.readFileSync(filePath,"utf-8");
            content = content.replace(rule.p1,rule.p2);
            fs.writeFileSync(filePath,content,{'flag':'w'});
            break;
          case "c":
            FileAppend(filePath,'\n'+rule.p1);
            break;
        }
      }
    }
  }
}